package com.edu.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.edu.entity.SysUserInfo;
import com.edu.user.mapper.SysUserInfoMapper;
import com.edu.user.service.ISysUserInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.edu.utils.JwtUtils;
import com.edu.utils.RsaUtils;
import com.edu.vo.PageResultVO;
import com.edu.vo.Result;

import org.springframework.core.io.ClassPathResource;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author jr
 * @since 2021-04-13
 */
@Service
public class SysUserInfoServiceImpl extends ServiceImpl<SysUserInfoMapper, SysUserInfo> implements ISysUserInfoService {

    @Override
    public Result login(SysUserInfo userInfo) throws Exception {

        if (StringUtils.isEmpty(userInfo)) return new Result(false,1,"参数错误！");


        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("account",userInfo.getAccount());
        SysUserInfo dbUser = this.baseMapper.selectOne(queryWrapper);

        if (StringUtils.isEmpty(dbUser)) return new Result(false,1,"账户不存在");

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

        if (!encoder.matches(userInfo.getPassword(),dbUser.getPassword())) return new Result(false,1,"密码错误");

        //获取私钥
        PrivateKey privateKey = null;
        try {
            privateKey = RsaUtils.getPrivateKey(ResourceUtils.getFile("classpath:rsa.pri").getPath());
        } catch (Exception e) {
            e.printStackTrace();
        }

        //颁发令牌
        dbUser.setPassword(null);
        String token = JwtUtils.generateTokenExpireInMinutes(dbUser, privateKey, 30);


        return new Result(true,0,"success",token);
    }


    /**
     * 验证令牌
     */
    public static byte[] readBytes3(InputStream in) throws IOException {
        BufferedInputStream bufin = new BufferedInputStream(in);
        int buffSize = 1024;
        ByteArrayOutputStream out = new ByteArrayOutputStream(buffSize);

        // System.out.println("Available bytes:" + in.available());

        byte[] temp = new byte[buffSize];
        int size = 0;
        while ((size = bufin.read(temp)) != -1) {
            out.write(temp, 0, size);
        }
        bufin.close();

        byte[] content = out.toByteArray();
        return content;
    }

    @Override
    public Result verifyToken(String token) {

        if (token == null) return  new Result(false,0,"非法参数");

        try {
            //加载公钥
            ClassPathResource resource = new ClassPathResource("rsa.pub");
            InputStream inputStream = resource.getInputStream();
            //PublicKey  publicKey = RsaUtils.getPublicKey(ResourceUtils.getFile("classpath:rsa.pub").getPath());
            PublicKey publicKey = RsaUtils.getPublicKey(readBytes3(inputStream));
            SysUserInfo infoFromToken = (SysUserInfo) JwtUtils.getInfoFromToken(token, publicKey, SysUserInfo.class);

            return new Result(true,0,"令牌有效",infoFromToken.getAccount());
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false,0,"令牌无效");
        }

    }

    @Override
    public PageResultVO<SysUserInfo> queryListByPage(Integer currentPage, Integer pageSize,String name) {


        //设置分页信息
        IPage<SysUserInfo> iPage = new Page(currentPage,pageSize);


        //条件构造器
        QueryWrapper<SysUserInfo> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(name)) {
            queryWrapper.eq("user_name", name);
        }


        IPage pageInfo = this.baseMapper.selectPage(iPage, queryWrapper);



        return new PageResultVO<SysUserInfo>(0,"用户信息查询",pageInfo.getTotal(),pageInfo.getRecords());
    }



    @Override
    public Result userAdd(SysUserInfo userInfo) {

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

        String encode = encoder.encode("123");

        userInfo.setPassword(encode);
        userInfo.setLoginTime(new Date());


        int code = this.baseMapper.insert(userInfo);

        if (code == 1 ) return new Result(true,0,"添加成功");
        else return new Result(false,1,"添加失败");

    }

    @Override
    public Result deleteById(Integer id) {

        int i = this.baseMapper.deleteById(id);
        if (i == 1) {
            return new Result(true,0,"删除成功");
        }else {
            return new Result(false,1,"删除失败");
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateUserById(SysUserInfo userInfo) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

        String encode = encoder.encode(userInfo.getPassword());
        userInfo.setPassword(encode);
        int i = this.baseMapper.updateById(userInfo);


        if (i == 1) {
            return new Result(true,0,"修改成功");
        }else {
            return new Result(false,1,"修改失败");
        }
    }


}
